﻿using System;
using System.IO;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

namespace YArchitech.MEP
{
	public class SharedParameters
	{
		public DefinitionFile CreateSharedParams(Application app, string sharedParamsPath)
		{
			string sharedParametersFilename = app.SharedParametersFilename;
			if (sharedParametersFilename.Length == 0 || !File.Exists(sharedParamsPath))
			{
				StreamWriter streamWriter = new StreamWriter(sharedParamsPath);
				streamWriter.Close();
				app.SharedParametersFilename = sharedParamsPath;
				sharedParametersFilename = app.SharedParametersFilename;
			}
			DefinitionFile result;
			try
			{
				result = app.OpenSharedParameterFile();
			}
			catch (Exception ex)
			{
				TaskDialog.Show("Revit", ex.Message);
				result = null;
			}
			return result;
		}

		public DefinitionGroup GetOrCreateSharedParamsGroup(DefinitionFile sharedParamsFile, string sharedParamsGroupName)
		{
			DefinitionGroup definitionGroup = sharedParamsFile.Groups.get_Item(sharedParamsGroupName);
			if (definitionGroup == null)
			{
				try
				{
					definitionGroup = sharedParamsFile.Groups.Create(sharedParamsGroupName);
				}
				catch (Exception ex)
				{
					TaskDialog.Show("Revit", ex.Message);
					definitionGroup = null;
				}
			}
			return definitionGroup;
		}

		public Definition GetOrCreateSharedParamsDefinition(DefinitionGroup sharedGroup, ParameterType sharedGroupType, string sharedGroupName, bool visible)
		{
			Definition definition = sharedGroup.Definitions.get_Item(sharedGroupName);
			if (definition == null)
			{
				ExternalDefinitionCreationOptions externalDefinitionCreationOptions = new ExternalDefinitionCreationOptions(sharedGroupName, sharedGroupType);
				externalDefinitionCreationOptions.Visible = false;
				definition = sharedGroup.Definitions.Create(externalDefinitionCreationOptions);
			}
			return definition;
		}

		public void BindParametersToCategory(UIApplication uiApp, Category category, Definition sharedParamDefinition)
		{
			Document document = uiApp.ActiveUIDocument.Document;
			CategorySet categorySet = uiApp.Application.Create.NewCategorySet();
			try
			{
				categorySet.Insert(category);
			}
			catch (Exception ex)
			{
				TaskDialog.Show("Revit", ex.Message);
			}
			using (SubTransaction subTransaction = new SubTransaction(document))
			{
				subTransaction.Start();
				try
				{
					Binding binding = uiApp.Application.Create.NewInstanceBinding(categorySet);
					document.ParameterBindings.Insert(sharedParamDefinition, binding);
				}
				catch (Exception ex2)
				{
					TaskDialog.Show("Revit", ex2.Message);
					subTransaction.RollBack();
				}
				finally
				{
					TransactionStatus status = subTransaction.GetStatus();
                    if ((int)status == 1)
					{
						subTransaction.Commit();
					}
                    else if ((int)status == 5 || (int)status == 6)
					{
						subTransaction.RollBack();
					}
				}
			}
		}

		public void DefineSharedParameters(UIApplication uiApp, string sharedParamsPath, Category category, string sharedParamsGroupName, ParameterType sharedParamsGroupType)
		{
			Application application = uiApp.Application;
			Document document = uiApp.ActiveUIDocument.Document;
			DefinitionFile sharedParamsFile = this.CreateSharedParams(application, sharedParamsPath);
			DefinitionGroup orCreateSharedParamsGroup = this.GetOrCreateSharedParamsGroup(sharedParamsFile, sharedParamsGroupName);
			bool allowsBoundParameters = category.AllowsBoundParameters;
			Definition orCreateSharedParamsDefinition = this.GetOrCreateSharedParamsDefinition(orCreateSharedParamsGroup, sharedParamsGroupType, sharedParamsGroupName, allowsBoundParameters);
			this.BindParametersToCategory(uiApp, category, orCreateSharedParamsDefinition);
		}
	}
}
